package com.bridgeintelligent.tag.bulkload.service.es;

import com.bridgeintelligent.tag.bulkload.api.fileload.FileLoadModel;
import com.bridgeintelligent.tag.bulkload.service.core.FileService;
import com.bridgeintelligent.tag.bulkload.service.es.query.IQueryCallback;
import lombok.AllArgsConstructor;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.reindex.BulkByScrollResponse;
import org.elasticsearch.script.Script;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import static com.bridgeintelligent.tag.bulkload.service.es.IESHelper.ES_SLICE_MAX;

/**
 * Created by JackCheung on 2019/9/7 8:06 PM.
 */
@Component
@AllArgsConstructor
public class ESUtils implements ApplicationListener<ContextRefreshedEvent> {

    private ESConfig esConfig;
    private FileService fileService;

    private static volatile IESHelper iesHelper;


    /**
     * 创建索引
     *
     * @param indexName
     */
    public static void createIndex(String indexName, String indexType) {
        iesHelper.createIndex(indexName, indexType);
    }

    /**
     * 查看索引下mapping字段集合
     *
     * @param indexName
     */
    public static Set<String> getIndexMapping(String indexName) {
        return iesHelper.getIndexMapping(indexName);
    }

    /**
     * 更新索引字段映射
     *
     * @param indexName
     * @param map
     */
    public static void updateIndexMapping(String indexName, String indexType, Map<String, String> map) {
        iesHelper.updateIndexMapping(indexName, indexType, map);
    }

    /**
     * 删除索引
     *
     * @param indexName
     */
    public static void delIndex(String indexName) {
        iesHelper.delIndex(indexName);
    }

    /**
     * 新增文档
     *
     * @param indexName
     * @param documentId
     * @param map
     */
    public static void insert(String indexName, String indexType, String documentId, Map<String, Object> map) {
        iesHelper.insert(indexName, indexType, documentId, map);
    }

    /**
     * 更新文档
     *
     * @param indexName
     * @param documentId
     * @param map
     */
    public static void update(String indexName, String indexType, String documentId, Map<String, Object> map) {
        iesHelper.update(indexName, indexType, documentId, map);
    }

    /**
     * 批量新增
     *
     * @param indexName
     * @param map
     */
    public static void bulkInsert(String indexName, String indexType, Map<String, Map<String, Object>> map) {
        iesHelper.bulkInsert(indexName, indexType, map);
    }

    /**
     * 批量更新
     *
     * @param indexName
     * @param map
     */
    public static void bulkUpdate(String indexName, String indexType, Map<String, Map<String, Object>> map) {
        iesHelper.bulkUpdate(indexName, indexType, map);
    }

    /**
     * 批量删除
     *
     * @param indexName
     * @param map
     */
    public static void bulkUpdateWithDel(String indexName, String indexType, Map<String, String> map) {
        iesHelper.bulkUpdateWithDel(indexName, indexType, map);
    }

    /**
     * 搜索文档
     *
     * @param indexName
     * @param docId
     */
    public static void serachDoc(String indexName, String indexType, String docId) {
        iesHelper.searchDoc(indexName, indexType, docId);
    }


    public static void scrollSearch(String indexName, FileLoadModel fileLoadModel, IQueryCallback iQueryCallback){
        iesHelper.scrollSearch(indexName,fileLoadModel,iQueryCallback);

    }

    public static void newScrollSearch(String indexName, FileLoadModel fileLoadModel, IQueryCallback iQueryCallback) {
        Lock lock = new ReentrantLock(true);
        CountDownLatch countDownLatch=new CountDownLatch(ES_SLICE_MAX);
        for (int i = 0; i < ES_SLICE_MAX; i++) {
            int finalI = i;
            new Thread(() -> iesHelper.newScrollSearch(indexName, fileLoadModel, iQueryCallback, finalI, lock,countDownLatch)).start();
        }
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }


    public static Map<String,String> multiSearchDoc(List<String> ids, String indexName, String[] includes){
        return iesHelper.multiSearchDoc(ids,indexName,includes);
    }

    /**
     * 更新文档
     *
     * @param indexName
     */
    public static BulkByScrollResponse updateByQuery(String indexName,QueryBuilder queryBuilder, Script script) {
        return iesHelper.updateByQuery(indexName,queryBuilder,script);
    }

    @SuppressWarnings("NullableProblems")
    @Override
    public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
        if (null == iesHelper) {
            initConnect();
        }
    }

    /**
     * 初始化ESHelper配置
     */
    private void initConnect() {
        if (null == iesHelper) {
            synchronized (ESUtils.class) {
                iesHelper = new ESHelper(esConfig,fileService);
            }
        }
    }
    public static RestHighLevelClient getClient() {
        return iesHelper.getClient();
    }

}
